package com.dream.plugin.simpledao.core;

import com.alibaba.fastjson.JSONObject;
import com.dream.plugin.simpledao.exception.NotGetTableDataException;
import com.dream.plugin.simpledao.mapper.SMapper;
import com.dream.plugin.simpledao.util.SPage;
import com.dream.plugin.simpledao.util.SStringUtil;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 用户调用部分
 */
public class SDao {

    private static SContainer container = SContainer.INSTANCE;

    private SMapper sMapper;

    public SDao(SMapper sMapper){
        new SScanTable();
        this.sMapper = sMapper;
    }

    public SDao(SMapper sMapper, String basePackage){
        new SScanTable(basePackage);
        this.sMapper = sMapper;
    }

    /**
     * 获取指定条件的记录数
     * @param tableName
     * @param condition
     * @return
     */
    private Integer getCountByCondition(String tableName, String condition){
        return sMapper.count(tableName, condition);
    }

    /**
     * 根据自定义条件分页查询
     * @param pojo
     * @param start
     * @param size
     * @param condition
     * @return
     */
    public SPage getBySqlConditionWithPage(Class pojo, Integer start, Integer size, String condition){
        if (start < 1)
            start = 1;
        if (size < 0)
            size = 1;
        String tableName = container.getTableName(pojo);
        String sqlCondition = SStringUtil.isEmpty(condition) ? "" : " where " + condition;
        Integer totalCount = getCountByCondition(tableName, sqlCondition);
        List<JSONObject> result = sMapper.selects(tableName,sqlCondition, (start-1) * size, size);
        List<Object> res = new ArrayList<>();
        for (JSONObject jsonObject : result){
            res.add(jsonObject.toJavaObject(pojo));
        }
        SPage sPage = new SPage(start, totalCount / size, size,  res);
        return sPage;
    }

    public SPage getBySqlConditionWithPage(Class pojo, Integer start, Integer size){
        return getBySqlConditionWithPage(pojo, start, size, null);
    }

    /**
     * 根据id查询
     * @param pojo
     * @param id
     * @return
     */
    public Object getById(Class pojo, Object id){
        String tableName = container.getTableName(pojo);
        return sMapper.selectById(tableName, container.getTableIdName(tableName), id).toJavaObject(pojo);
    }


    /**
     * 插入
     * @param pojo
     * @return
     */
    public Integer insert(Object pojo){
        Class clazz = pojo.getClass();
        String tableName = container.getTableName(clazz);
        Map<String,Object> tableData;
        try {
            tableData = SStringUtil.getTableData(pojo, clazz);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
            throw new NotGetTableDataException();
        }
        List<String> columns = container.getTableColumns(tableName);
        StringBuilder params = new StringBuilder();
        for (String column : columns){
            Object columnVal = tableData.get(column);
            if (columnVal == null){
                params.append("null,");
                continue;
            }
            params.append("'");
            params.append(columnVal);
            params.append("',");
        }
        params.deleteCharAt(params.lastIndexOf(","));
        String columnsStr = String.join(",", columns);
        return sMapper.insert(tableName,columnsStr, params.toString());
    }

    /**
     * 修改除主键外的所有元素
     * @param pojo
     * @return
     */
    public Integer update(Object pojo){
        Class clazz = pojo.getClass();
        String tableName = container.getTableName(clazz);
        Map<String,Object> tableData;
        try {
            tableData = SStringUtil.getTableData(pojo, clazz);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
            throw new NotGetTableDataException();
        }
        List<String> columns = container.getTableColumns(tableName);
        String idName = container.getTableIdName(tableName);
        String settings = columns.stream()
                .filter(item -> ! item.equals(idName))
                .map(item ->tableData.get(item) == null ? item + "=null" : String.format("%s='%s'", item, tableData.get(item)))
                .collect(Collectors.joining(","));
        return sMapper.update(tableName, settings, idName, tableData.get(idName));
    }

    /**
     * 根据id删除
     * @param c
     * @param id
     * @return
     */
    public Integer delete(Class c, Object id){
        String tableName = container.getTableName(c);
        String idName = container.getTableIdName(tableName);
        return sMapper.delete(tableName, idName, id);
    }

}
